<?php
//    +----------------------------------------------------------------------
//    | Copyright (c) 2015-2035 http://www.hdphp.cn All rights reserved.
//    | Licensed ( http://www.hdphp.cn/licenses/ )
//    | Author: Jack <sophia2152@qq.com>
//    | 官方网址: http://www.hdphp.cn
//    | 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用。
//    | 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
//    +----------------------------------------------------------------------
namespace app\services\system\admin;

use app\services\BaseServices;
use app\dao\system\admin\SystemAdminDao;
use app\services\system\log\SystemLoginLogServices;
use app\services\system\SystemMenusServices;
use app\services\user\UserServices;
use hdphp\exceptions\AdminException;
use think\facade\Cache;

/**
 * Class：SystemAdminServices
 * 创建人：Jack
 * 创建时间：2023/3/21 7:48 PM
 * @package app\services\system\admin
 * @mixin SystemAdminDao
 */
class SystemAdminServices extends BaseServices
{

    /**
     * SystemAdminServices constructor.
     * @param SystemAdminDao $dao
     */
    public function __construct(SystemAdminDao $dao)
    {
        $this->dao = $dao;
    }

    /**
     * 注释：后台登陆获取菜单获取token
     * 创建人：Jack
     * 创建时间：2023/3/23 15:53
     * @param string $username
     * @param string $password
     * @param string $type
     * @param bool $is_mobile
     * @return array
     */
    public function login(string $username, string $password, string $type, bool $is_mobile = false)
    {
        $userInfo = $this->verifyLogin($username, $password, $is_mobile);
        $tokenInfo = $this->createToken($userInfo->uid, $type, $userInfo->password);
        /** @var SystemMenusServices $services */
        $services = app()->make(SystemMenusServices::class);
        [$menus, $uniqueAuth] = $services->getMenusList($userInfo->roles, (int)$userInfo['level']);
        return [
            'token' => $tokenInfo['token'],
            'expires_in' => $tokenInfo['params']['exp'],
            'expires_time' => date('Y-m-d H:i:s', $tokenInfo['params']['exp']),
            'menus' => $menus,
            'unique_auth' => $uniqueAuth,
            'user_info' => [
                'id' => $userInfo['uid'],
                'tel' => $userInfo['tel'],
                'face' => $userInfo['face'],
                'email' => $userInfo['email'],
                'mobile' => $userInfo['mobile'],
                'username' => $userInfo['username'],
                'true_name' => $userInfo['true_name'],
                'department' => $userInfo['department']
            ]
        ];
    }

    /**
     * 注释：登录验证
     * 创建人：Jack
     * 创建时间：2023/3/23 15:38
     * @param string $username
     * @param string $password
     * @param bool $is_mobile
     * @return array
     */
    public function verifyLogin(string $username, string $password, bool $is_mobile = false)
    {
        if (empty($username)) throw new AdminException('please enter the correct username');
        if (empty($password)) throw new AdminException('please enter the correct password');
        $username = trim($username);
        $key = 'login_identifying_code_' . $username;
        /** @var UserServices $userServices */
        $userServices = app()->make(UserServices::class);
        /** @var SystemLoginLogServices $systemLoginLogServices */
        $systemLoginLogServices = app()->make(SystemLoginLogServices::class);
        if ($is_mobile) {
            $userInfo = $userServices->phoneByAdmin($username);
        } else {
            $userInfo = $userServices->usernameByAdmin($username);
        }
        if (!$userInfo) {
            Cache::inc($key);
            throw new AdminException('user not exist');
        }
        $uid = $userInfo->uid;
        // 判断登录次数
        $login_time = $systemLoginLogServices->getCount(['uid' => $uid, 'status' => 0, 'time' => 'today', 'timeKey' => 'login_time']);
        if ($login_time > 5) {
            throw new AdminException('login times exceeds limit');
        }
        $adminInfo = $this->dao->uidByAdmin($uid);
        if ($adminInfo) {
            if (!$adminInfo->status) {
                Cache::inc($key);
                throw new AdminException('user banned login');
            }
            $login_ok = FALSE;
            $ip = app('request')->ip();
            // 判断是否设置独立密码
            if ($adminInfo->password && (md5(md5($password) . $adminInfo->factor) == $adminInfo->password)) {

                $login_ok = TRUE;
            } elseif ($adminInfo->password) {
                $login_ok = FALSE;
            } elseif (md5(md5($password) . $userInfo->factor) == $userInfo->password) {
                $login_ok = TRUE;
            }
            if ($login_ok === TRUE) {
                $adminInfo->last_time = time();
                $adminInfo->last_ip = $ip;
                $adminInfo->login_count++;
                $adminInfo->save();
                $systemLoginLogServices->insertLoginLog($uid, 1, $ip);
                $adminInfo['username'] = $userInfo['username'];
                $adminInfo['password'] = $adminInfo->password ? $adminInfo->password : $userInfo->password;
                return $adminInfo;
            } else {
                // 验证失败
                Cache::inc($key);
                $systemLoginLogServices->insertLoginLog($uid, 0, $ip);
                throw new AdminException('username or password error');
            }
        } else {
            Cache::inc($key);
            throw new AdminException('user not exist');
        }
    }

}
